home *** CD-ROM | disk | FTP | other *** search
/ Technotools / Technotools (Chestnut CD-ROM)(1993).ISO / os2tools / bnklysrc / f_recv.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-05-05  |  25.6 KB  |  869 lines

  1. /*--------------------------------------------------------------------------*/
  2. /*                                                                          */
  3. /*                                                                          */
  4. /*      ------------         Bit-Bucket Software <no-Inc>                   */
  5. /*      \ 10001101 /         Writers and Distributors of                    */
  6. /*       \ 011110 /          No-Cost<no-tm> Software.                       */
  7. /*        \ 1011 /                                                          */
  8. /*         ------                                                           */
  9. /*                                                                          */
  10. /*  Copyright (C) 1987, 1988, 1989 by Robert Hartman and Vincent Perriello  */
  11. /*                                                                          */
  12. /*                                                                          */
  13. /*         GENERAL PURPOSE FILE RECEPTION (Xmodem/YModem/Sealink)           */
  14. /*                                                                          */
  15. /*                                                                          */
  16. /*    For complete  details  of the licensing restrictions, please refer    */
  17. /*    to the License  agreement,  which  is published in its entirety in    */
  18. /*    the MAKEFILE and BT.C, and also contained in the file LICENSE.210.    */
  19. /*                                                                          */
  20. /*    USE  OF THIS FILE IS SUBJECT TO THE  RESTRICTIONS CONTAINED IN THE    */
  21. /*    BINKLEYTERM  LICENSING  AGREEMENT.  IF YOU DO NOT FIND THE TEXT OF    */
  22. /*    THIS  AGREEMENT IN ANY OF THE  AFOREMENTIONED FILES,  OR IF YOU DO    */
  23. /*    NOT HAVE THESE FILES,  YOU SHOULD  IMMEDIATELY CONTACT THE AUTHORS    */
  24. /*    AT THE  ADDRESSES LISTED BELOW.  IN NO EVENT SHOULD YOU PROCEED TO    */
  25. /*    USE   THIS  FILE  WITHOUT  HAVING   ACCEPTED  THE  TERMS  OF   THE    */
  26. /*    BINKLEYTERM  LICENSING AGREEMENT,  OR SUCH OTHER  AGREEMENT AS YOU    */
  27. /*    ARE ABLE TO REACH WITH THE AUTHORS.                                   */
  28. /*                                                                          */
  29. /*                                                                          */
  30. /*    The Authors can be reached at the following addresses:                */
  31. /*                                                                          */
  32. /*    Robert C. Hartman                      Vincent E. Perriello           */
  33. /*    Spark Software                         VEP Software                   */
  34. /*    427-3 Amherst Street                   111 Carroll Street             */
  35. /*    CS2032, Suite 232                      Naugatuck, CT 06770            */
  36. /*    Nashua, NH 03061                                                      */
  37. /*                                                                          */
  38. /*    FidoNet 1:132/101                      FidoNet 1:141/491              */
  39. /*    Data    (603) 888-8179                 Data    (203) 729-7569         */
  40. /*                                                                          */
  41. /*    Please feel free to contact us at any time to share your comments     */
  42. /*    about our software and/or licensing policies.                         */
  43. /*                                                                          */
  44. /*                                                                          */
  45. /*  This module is based largely on a similar module in OPUS-CBCS V1.03b.   */
  46. /*  The original work is (C) Copyright 1987, Wynn Wagner III. The original  */
  47. /*  author has graciously allowed us to use his code in this work.          */
  48. /*                                                                          */
  49. /*--------------------------------------------------------------------------*/
  50.  
  51. #include <sys/types.h>
  52. #include <ctype.h>
  53. #include <stdio.h>
  54. #include <time.h>
  55. #include <conio.h>
  56. #include <stdlib.h>
  57. #include <dos.h>
  58. #include <string.h>
  59. #include <io.h>
  60.  
  61. #ifdef __TURBOC__
  62. #include "tc_utime.h"
  63. #include <alloc.h>
  64. #else
  65. #include <sys/utime.h>
  66. #include <malloc.h>
  67. #endif
  68.  
  69. #include "com.h"
  70. #include "xfer.h"
  71. #include "zmodem.h"
  72. #include "keybd.h"
  73. #include "sbuf.h"
  74. #include "sched.h"
  75. #include "externs.h"
  76. #include "prototyp.h"
  77. #include "find.h"   /*PLF Fri  05-05-1989  23:35:56 */
  78.  
  79. static void SendACK (void);
  80. static void SendNAK (void);
  81. static void getblock (void);
  82.  
  83. /*--------------------------------------------------------------------------*/
  84. /* LOCALS                                                                   */
  85. /*--------------------------------------------------------------------------*/
  86. static long block_number;
  87. static long base_block;
  88. static char *stat_msg;
  89. static int sliding;
  90. static int block_size;
  91. static int do_chksum;
  92. static int errs;
  93. static int real_errs;
  94. static long fsize1;
  95. static int fsize2;
  96. static char *buffer;
  97. static FILE *infile;
  98. static char *_fpath;
  99. static struct zero_block *header;
  100. static char final_name[80];
  101. static int first_block;                          /* 1 = first block/Matrix
  102.                                                   * packet */
  103.  
  104. static char *receiving = "Receiving  ";
  105. static int may_be_seadog;
  106. static int netmail;
  107. static int recv_ackless;
  108. static int did_nak;
  109. static long filesecs;
  110.  
  111. #define two_s "%s%s"
  112.  
  113.  
  114.  
  115. /*--------------------------------------------------------------------------*/
  116. /* SEND ACK                                                                 */
  117. /*--------------------------------------------------------------------------*/
  118. static void SendACK ()
  119. {
  120.    if ((!recv_ackless) || (block_number == 0))
  121.       {
  122.        SENDBYTE (ACK);
  123.       if (sliding)
  124.          {
  125.          SENDBYTE ((unsigned char) block_number);
  126.          SENDBYTE ((unsigned char) (~(block_number)));
  127.          }
  128.  
  129.       if (block_number <= fsize1)
  130.          {
  131.          /* No-nonsense status line.  Don't waste time with frills... */
  132.          if (fullscreen && un_attended)
  133.             {
  134.             sb_move (filewin, 2, 2);
  135.             sb_puts (filewin, ultoa (((unsigned long) (block_number)), e_input, 10));
  136.             sb_show ();
  137.             }
  138.          else
  139.             {
  140.             gotoxy (locate_x, locate_y);
  141.             cputs (ultoa (((unsigned long) (block_number)), e_input, 10));
  142.             }
  143.          }
  144.       }
  145.  
  146.    else if (((!(block_number & 0x001F)) && (block_number < fsize1))
  147.             || (block_number == fsize1))
  148.       {
  149.       /* In Overdrive only put out last block and n/32 */
  150.       if (fullscreen && un_attended)
  151.          {
  152.          sb_move (filewin, 2, 2);
  153.          sb_puts (filewin, ultoa (((unsigned long) (block_number)), e_input, 10));
  154.          sb_putc (filewin, '*');
  155.          sb_show ();
  156.          }
  157.       else
  158.          {
  159.          gotoxy (locate_x, locate_y);
  160.          cputs (ultoa (((unsigned long) (block_number)), e_input, 10));
  161. /*PLF    bdos (9, (unsigned int) "*$", 0); */
  162.          putch('*'); /*PLF Fri  05-05-1989  06:58:31 */
  163.          }
  164.       }
  165.  
  166.    errs = 0;
  167. }                                                /* SendACK */
  168.  
  169.  
  170.  
  171. /*--------------------------------------------------------------------------*/
  172. /* SEND NAK                                                                 */
  173. /*--------------------------------------------------------------------------*/
  174. static void SendNAK ()
  175. {
  176.    int i;
  177.    long t1;
  178.  
  179.    errs++;
  180.    real_errs++;
  181.    if (errs > 6)
  182.       {
  183.       stat_msg = FUBAR_msg;
  184.       return;
  185.       }
  186.  
  187.    if (++did_nak > 8)
  188.       {
  189.       recv_ackless = 0;
  190.       }
  191.  
  192.    CLEAR_INBOUND ();
  193.  
  194.    /*--------------------------------------------------------------------*/
  195.    /* Let the connection cool its heels.                                 */
  196.    /*--------------------------------------------------------------------*/
  197.    if (!recv_ackless)
  198.       {
  199.       /* Set a timer for waiting */
  200.       t1 = timerset (3000);
  201.       if ((base_block != block_number) || (errs > 1))
  202.          do
  203.             {
  204.             i = TIMED_READ (1);
  205.             if (!CARRIER)
  206.                return;
  207.             if (timeup (t1))
  208.                break;
  209.             }
  210.          while (i >= 0);
  211.       }
  212.  
  213.    if (block_number > base_block)
  214.       SENDBYTE (NAK);
  215.    else
  216.       {
  217.       if ((errs < 5) && (!do_chksum))
  218.          SENDBYTE ('C');
  219.       else
  220.          {
  221.          do_chksum = 1;
  222.          SENDBYTE (NAK);
  223.          }
  224.       }
  225.  
  226.    if (sliding)
  227.       {
  228.       SENDBYTE ((unsigned char) block_number);
  229.       SENDBYTE ((unsigned char) (~(block_number)));
  230.       }
  231.  
  232.    if (block_number <= fsize1)
  233.       {
  234.       /* No time for anything but the bare essentials... */
  235.       if (fullscreen && un_attended)
  236.          {
  237.          sb_move (filewin, 2, 2);
  238.          sb_puts (filewin, ultoa (((unsigned long) (block_number)), e_input, 10));
  239.          sb_show ();
  240.          }
  241.       else
  242.          {
  243.          gotoxy (locate_x, locate_y);
  244.          cputs (ultoa (((unsigned long) (block_number)), e_input, 10));
  245.          }
  246.       }
  247. }                                                /* SendNAK */
  248.  
  249. /*--------------------------------------------------------------------------*/
  250. /* GET BLOCK                                                                */
  251. /*--------------------------------------------------------------------------*/
  252. static void getblock ()
  253. {
  254.    register int i;
  255.    register char *sptr;
  256.  
  257.    char *p;
  258.    unsigned int crc;
  259.    int in_char;
  260.    int is_resend;
  261.    int blockerr;
  262.    unsigned char chksum;
  263.    char junkbuff[128];
  264.  
  265.    blockerr = is_resend = 0;
  266.    chksum = '\0';
  267.  
  268.  
  269.    /*--------------------------------------------------------------------*/
  270.    /* HEADER: Block number                                               */
  271.    /*--------------------------------------------------------------------*/
  272.    in_char = TIMED_READ (5);
  273.    if (in_char != ((int)(block_number) & 0xff))
  274.       {
  275.       if (in_char < (int)block_number)
  276.          is_resend = 1;
  277.       else if ((block_number) || (in_char != 1))
  278.          {
  279.          blockerr++;
  280.          stat_msg = SYNC_msg;
  281.          }
  282.       else block_number = 1;
  283.       }
  284.  
  285.    /*--------------------------------------------------------------------*/
  286.    /* HEADER: Complement of the block number                             */
  287.    /*--------------------------------------------------------------------*/
  288.    i = TIMED_READ (5);
  289.    if ((i & 0xff) != ((~in_char) & 0xff))
  290.       {
  291.       blockerr++;
  292.       stat_msg = CMPL_msg;
  293.       }
  294.  
  295.    /*--------------------------------------------------------------------*/
  296.    /* DATA                                                               */
  297.    /*--------------------------------------------------------------------*/
  298.    for (sptr = buffer, i = 0; i < block_size; i++, sptr++)
  299.       {
  300.       in_char = TIMED_READ (5);
  301.       if (in_char < 0)                           /* We get EOF for timeout or
  302.                                                   * carrier */
  303.          {
  304.          if (CARRIER)                            /* If we have carrier it was
  305.                                                   * timeout */
  306.             {
  307.             SendNAK ();
  308.             stat_msg = TIME_msg;
  309.             }
  310.          return;                                 /* return in either case */
  311.          }
  312.       sptr[0] = (char) in_char;
  313.       }
  314.  
  315.    /*--------------------------------------------------------------------*/
  316.    /* CHECK                                                              */
  317.    /*--------------------------------------------------------------------*/
  318.    if (do_chksum)
  319.       {
  320.       for (sptr = buffer, i = 0; i < block_size; i++, sptr++)
  321.          chksum += sptr[0];
  322.  
  323.       if (TIMED_READ (5) != chksum)
  324.          {
  325.          stat_msg = CHK_msg;
  326.          blockerr++;
  327.          }
  328.       }
  329.    else
  330.       {
  331.       unsigned int lsb, msb;
  332.  
  333.       for (sptr = buffer, i = crc = 0; i < block_size; i++, sptr++)
  334.          crc = xcrc (crc, (byte) sptr[0]);
  335.  
  336.       msb = TIMED_READ (3);
  337.       lsb = TIMED_READ (3);
  338.       if ((lsb < 0) || (msb < 0))
  339.          {
  340.          stat_msg = SHRT_msg;
  341.          if (!block_number)
  342.             sliding = 0;
  343.          blockerr++;
  344.          }
  345.       else if (((msb << 8) | lsb) != crc)
  346.          {
  347.          stat_msg = CRC_msg;
  348.          blockerr++;
  349.          }
  350.       }
  351.  
  352.    if (blockerr)
  353.       SendNAK ();
  354.    else
  355.       {
  356.       SendACK ();
  357.       if (is_resend)
  358.          return;
  359.  
  360.       if (block_number)
  361.          {
  362.          if (block_number < fsize1)
  363.             fwrite (buffer, block_size, 1, infile);
  364.          else if (block_number == fsize1)
  365.             fwrite (buffer, fsize2, 1, infile);
  366.  
  367.          if (first_block)
  368.             {
  369.             struct _pkthdr *packet;
  370.  
  371.             packet = (struct _pkthdr *) buffer;
  372.             if (!remote_capabilities)
  373.                {
  374.                remote_net = packet->orig_net;
  375.                remote_node = packet->orig_node;
  376.                remote_zone = packet->orig_zone;
  377.                }
  378.             first_block = 0;
  379.             if (who_is_he)
  380.                {
  381.                if (nodefind (remote_zone, remote_net, remote_node, 1))
  382.                   {
  383.                   if (!remote_zone)
  384.              remote_zone = found_zone;
  385.  
  386.                   sprintf (junkbuff, " Remote System: %s (%u:%u/%u)",
  387.                            newnodedes.SystemName,
  388.                            remote_zone,
  389.                            remote_net,
  390.                            remote_node);
  391.                   }
  392.                else
  393.                   {
  394.                   sprintf (junkbuff, " Remote System: UNKNOWN - FSC-0001 Mailer (%u:%u/%u)",
  395.                            remote_zone,
  396.                            remote_net,
  397.                            remote_node);
  398.                   }
  399.  
  400.                last_type (2, remote_zone, remote_net, remote_node);
  401.                status_line (junkbuff);
  402.                who_is_he = 0;
  403.                }
  404.             }
  405.          }
  406.       else
  407.          {
  408.          if (!first_block)
  409.             {
  410.             sptr = &(header->name[0]);
  411.             if (netmail)
  412.                invent_pkt_name (sptr);
  413.  
  414.             for (i = 0; ((sptr[i]) && (i < 17)); i++)
  415.                if (sptr[i] <= ' ')
  416.                   sptr[i] = '\0';
  417.  
  418.             if (sptr[0])
  419.                {
  420.                sprintf (final_name, two_s, _fpath, sptr);
  421.                sptr = final_name;
  422.                fancy_str (sptr);
  423.  
  424.                i = strlen (final_name) - 1;
  425.  
  426.                if (netmail)
  427.                    p = check_netfile (sptr);
  428.                else
  429.                    p = receiving;
  430.  
  431.                if (un_attended && fullscreen)
  432.                   {
  433.                   clear_filetransfer ();
  434.                   sb_move (filewin, 1, 2);
  435.                   sb_puts (filewin, p);
  436.                   sb_puts (filewin, sptr);
  437.                   sb_show ();
  438.                   }
  439.                else if (locate_y > 1)
  440.                   {
  441.                   gotoxy (2, locate_y - 1);
  442.                   cprintf (p);
  443.                   cputs (sptr);
  444.                   }
  445.                }
  446.             else
  447.                status_line ("!Grunged hdr");
  448.             }
  449.  
  450.          if (header->size)
  451.             {
  452.             fsize1 = (long) (header->size / 128L);
  453.             if (fsize2 = (int) (header->size % 128))
  454.                ++fsize1;
  455.             else
  456.                fsize2 = 128;
  457.             sprintf (junkbuff, "%s %ld blks", (netmail) ? "     " : "", fsize1);
  458.             if (un_attended && fullscreen)
  459.                {
  460.                sb_puts (filewin, junkbuff);
  461.                sb_show ();
  462.                }
  463.             else
  464.                cprintf ("%s", junkbuff);
  465.             }
  466.  
  467.          if (header->time)
  468.             {
  469.             filesecs = header->time;
  470.             }
  471.          else
  472.             {
  473.             filesecs = -1;
  474.             }
  475.  
  476.          if (header->moi[0])
  477.             {
  478.             if (un_attended && fullscreen)
  479.                {
  480.                sprintf (junkbuff, " from %s", header->moi);
  481.                sb_puts (filewin, junkbuff);
  482.                sb_show ();
  483.                }
  484.             else
  485.                cprintf (" from %s", header->moi);
  486.             }
  487.  
  488.          if ((cur_baud >= 9600) && header->noacks && !no_overdrive)
  489.             {
  490.             recv_ackless = 1;
  491.             }
  492.  
  493.          if (!netmail)
  494.             {
  495.             if (!(un_attended && fullscreen))
  496.                {
  497.                set_xy (NULL);
  498.                locate_x += 2;
  499.                }
  500.             }
  501.          }
  502.       block_number++;
  503.       }
  504. }                                                /* getblock */
  505.  
  506. /*--------------------------------------------------------------------------*/
  507. /* GENERAL PURPOSE FILE RECEIPTION ROUTINE                                  */
  508. /*--------------------------------------------------------------------------*/
  509. char *
  510.  receive_file (fpath, fname, protocol)
  511. char *fpath, *fname, protocol;
  512. {
  513.    char tmpname[80];
  514.    int in_char;
  515.    struct utimbuf times;
  516.    long t1;
  517.  
  518.    did_nak = 0;
  519.    filesecs = -1;
  520.    XON_DISABLE ();
  521.  
  522.    if (protocol == 'F')
  523.       {
  524.       may_be_seadog = 1;
  525.       netmail = 0;
  526.       protocol = 'S';
  527.       first_block = 0;
  528.       }
  529.    else if (protocol == 'B')
  530.       {
  531.       protocol = 'S';
  532.       netmail = 1;
  533.       may_be_seadog = 1;
  534.       first_block = 1;
  535.       }
  536.    else
  537.       {
  538.       may_be_seadog = 0;
  539.       netmail = 0;
  540.       first_block = 0;
  541.       }
  542.  
  543.    CLEAR_IOERR ();
  544.    fsize1 = 65535;
  545.    if (fname)
  546.       for (in_char = 0; fname[in_char]; in_char++)
  547.          if ((fname[in_char] == '*') || (fname[in_char] == '?'))
  548.             fname[0] = '\0';
  549.  
  550.    _fpath = fpath;
  551.    sliding = 1;
  552.    base_block =
  553.       do_chksum =
  554.       errs = 0;
  555.    block_size = 128;
  556.  
  557.    locate_y = wherey ();
  558.    locate_x = 3 + wherex ();
  559.  
  560.    switch (protocol)
  561.       {
  562.       case 'X':
  563.          base_block = 1;
  564.          sliding = 0;
  565.          break;
  566.       case 'Y':
  567.          base_block = 1;
  568.          sliding = 0;
  569.          block_size = 1024;
  570.          break;
  571.       case 'S':
  572.          break;
  573.       case 'T':
  574.          break;
  575.       case 'M':
  576.          base_block = 1;
  577.          sliding = 0;
  578.          break;
  579.       default:
  580.          status_line ("!Protocol??");
  581.          return NULL;
  582.       }
  583.  
  584.    block_number = base_block;
  585.  
  586.    sprintf (tmpname, "%s_TMP_.$$$", fpath);
  587.    sprintf (final_name, two_s, _fpath, (fname && fname[0]) ? fname : "UNKNOWN.$$$");
  588.  
  589.    infile = fopen (tmpname, write_binary);
  590.    if (got_error (CREATE_msg, tmpname))
  591.       return (NULL);
  592.    if (isatty (fileno (infile)))
  593.       {
  594.       errno = 1;
  595.       got_error (DEVICE_msg, tmpname);
  596.       fclose (infile);
  597.       return (NULL);
  598.       }
  599.  
  600.    buffer = Txbuf;
  601.    header = (struct zero_block *) buffer;
  602.    if (!buffer)
  603.       {
  604.       status_line ("!MEM:ulbuf");
  605.       return (NULL);
  606.       }
  607.  
  608.    if (!(un_attended && fullscreen))
  609.       {
  610.       set_xy (NULL);
  611.       locate_x += 2;
  612.       }
  613.    stat_msg = NULL;
  614.    throughput (0, 0L);
  615.  
  616.    /* If we did the SEAdog kludge, then don't send another NAK */
  617.    if (!may_be_seadog)
  618.       SendNAK ();
  619.  
  620.    t1 = timerset (300);
  621.    real_errs = 0;
  622.  
  623. loop_top:
  624.  
  625.    if (got_ESC ())
  626.       {
  627.       stat_msg = KBD_msg;
  628.       goto fubar;
  629.       }
  630.  
  631.    in_char = TIMED_READ (4);
  632.  
  633.    switch (in_char)
  634.       {
  635.       case SOH:
  636.          /*--------------------------------------------*/
  637.          /* SOH: 128 byte block header                 */
  638.          /*--------------------------------------------*/
  639.          block_size = 128;
  640.          getblock ();
  641.          t1 = timerset (300);
  642.          break;
  643.  
  644.       case STX:
  645.          /*--------------------------------------------*/
  646.          /* STX: YModem 1k block header                */
  647.          /*--------------------------------------------*/
  648.          block_size = 1024;
  649.          getblock ();
  650.          t1 = timerset (300);
  651.          break;
  652.  
  653.       case SYN:
  654.          /*--------------------------------------------*/
  655.          /* SYN: TeLink Zero block header              */
  656.          /*--------------------------------------------*/
  657.          do_chksum = 1;
  658.          getblock ();
  659.          do_chksum = 0;
  660.          t1 = timerset (300);
  661.          break;
  662.  
  663.       case CAN:
  664.          /*--------------------------------------------*/
  665.          /* CAN                                        */
  666.          /*--------------------------------------------*/
  667.          if (TIMED_READ (2) == CAN)
  668.             {
  669.             stat_msg = CAN_msg;
  670.             goto fubar;
  671.             }
  672.          t1 = timerset (300);
  673.          break;
  674.  
  675.       case EOT:
  676.          /*--------------------------------------------*/
  677.          /* EOT                                        */
  678.          /*--------------------------------------------*/
  679.          stat_msg = EOT_msg;
  680.          t1 = timerset (20);
  681.          while (!timeup (t1))
  682.             {
  683.             TIMED_READ (0);
  684.             time_release ();
  685.             }
  686.          if (block_number)
  687.             goto done;
  688.          else goto fubar;
  689.  
  690.       default:
  691.          /*--------------------------------------------*/
  692.          /* Default                                    */
  693.          /*--------------------------------------------*/
  694.          if (in_char > 0)
  695.             {
  696.             if (!may_be_seadog)
  697.                {
  698.                if (!(fullscreen && un_attended))
  699.                   {
  700.                   gotoxy (locate_x, locate_y);
  701.                   cprintf ("??? [%Xh, blk %d] ", in_char, block_number);
  702.                   set_xy (receiving);
  703.                   }
  704.                }
  705.             }
  706.          else if (!CARRIER)                      /* Was it a timeout or
  707.                                                   * carrier loss? */
  708.             goto lost;                           /* Carrier, get out of here          */
  709.  
  710.          /*
  711.           * Debris is tolerable for up to the amount of time we are willing
  712.           * to wait for a start of a block.  Right now it is 10 seconds. 
  713.           */
  714.  
  715.          /*
  716.           * If may_be_seadog is set, then we know we should get an SOH pretty
  717.           * soon 
  718.           */
  719.          if (timeup (t1) || !may_be_seadog)
  720.             SendNAK ();
  721.          break;
  722.       }                                          /* switch */
  723.  
  724.    if (errs > 14)
  725.       {
  726.       stat_msg = FUBAR_msg;
  727.       goto fubar;
  728.       }
  729.  
  730.    else if (got_error (WRITE_msg, fname))
  731.       {
  732.       stat_msg = IO_msg;
  733.       goto fubar;
  734.       }
  735.  
  736.    if (stat_msg)
  737.       {
  738.       if (fullscreen && un_attended)
  739.          {
  740.          sb_puts (filewin, stat_msg);
  741.          sb_puts (filewin, "                         ");
  742.          sb_show ();
  743.          }
  744.       else
  745.          {
  746.          cputs (stat_msg);
  747.          cputs ("                         ");
  748.          }
  749.       stat_msg = NULL;
  750.       }
  751.    goto loop_top;
  752.  
  753. lost:
  754.  
  755.    stat_msg = CARRIER_msg;
  756.  
  757. fubar:
  758.  
  759.    if (infile)
  760.       {
  761.       fclose (infile);
  762.       got_error (CLOSE_msg, tmpname);
  763.       unlink (tmpname);
  764.       got_error (UNLINK_msg, tmpname);
  765.       }
  766.  
  767.    CLEAR_OUTBOUND ();
  768.  
  769.    if (stat_msg != EOT_msg)
  770.       {
  771.       for (in_char = 0; in_char < 5; in_char++)
  772.          SENDBYTE (CAN);
  773.  
  774.       status_line ("!File not received: %s", stat_msg);
  775.       }
  776.  
  777.    CLEAR_INBOUND ();
  778.    return NULL;
  779.  
  780.  
  781. done:
  782.  
  783.    recv_ackless = 0;
  784.    SendACK ();
  785.  
  786.    if (infile)
  787.       {
  788.       int i, j, k;
  789.       FSCAN *dh;    /*PLF Fri  05-05-1989  23:30:39 */
  790.  
  791.       fclose (infile);
  792.       got_error (CLOSE_msg, tmpname);
  793.  
  794.       i = strlen (tmpname) - 1;
  795.       j = strlen (final_name) - 1;
  796.  
  797.       if (tmpname[i] == '.')
  798.          tmpname[i] = '\0';
  799.       if (final_name[j] == '.')
  800.          {
  801.          final_name[j] = '\0';
  802.          --j;
  803.          }
  804.  
  805.       i = 0;
  806.       k = is_arcmail (final_name, j);
  807.       if ((!overwrite) || k)
  808.          {
  809.          while (rename (tmpname, final_name))
  810.             {
  811.             if (isdigit (final_name[j]))
  812.                final_name[j]++;
  813.             else final_name[j] = '0';
  814.             if (!isdigit (final_name[j]))
  815.                return (tmpname);
  816.             i = 1;
  817.             }
  818.          CLEAR_IOERR ();
  819.          }
  820.       else
  821.          {
  822.          unlink (final_name);
  823.          rename (tmpname, final_name);
  824.          }
  825.       if (i)
  826.          {
  827.          if (locate_y && !(fullscreen && un_attended))
  828.             gotoxy (2, locate_y - 1);
  829.          status_line ("+Dupe file renamed: %s", final_name);
  830.          }
  831.  
  832.       if (filesecs != -1)
  833.          {
  834.          tzset ();
  835.          times.modtime = filesecs + timezone;
  836.          times.actime = filesecs + timezone;
  837.          utime (final_name, ×);
  838.          }
  839.       dh = opendir();   /*PLF Fri  05-05-1989  23:32:06 */
  840.       if (!findfirst(final_name, _A_NORMAL, dh)) /*PLF Fri  05-05-1989  23:32:37 */
  841.          {
  842.          if (!i)
  843.             {
  844.             if (locate_y && !(fullscreen && un_attended))
  845.                gotoxy (2, locate_y - 1);
  846.             }
  847.          if (real_errs > 4)
  848.             status_line ("+Corrected %d errors in %d blocks",
  849.                          real_errs, fsize1);
  850.          status_line ("+Received-S %s", final_name);
  851.          throughput (1, dh->size);      /*PLF Fri  05-05-1989  23:33:38 */
  852.  
  853.          update_files (0);
  854.  
  855.          dh->size /= 1024L;             /*PLF Fri  05-05-1989  23:33:41 */
  856.          strcpy (final_name, dh->name); /*PLF Fri  05-05-1989  23:33:43 */
  857.          closedir(dh);                  /*PLF Fri  05-05-1989  23:34:18 */
  858.          CLEAR_IOERR ();
  859.          return final_name;                      /* signal what file we got */
  860.          }
  861.       closedir(dh);                  /*PLF Fri  05-05-1989  23:34:18 */
  862.       }
  863.    CLEAR_IOERR ();
  864.    return NULL;
  865.  
  866. }
  867.  
  868. /* END OF FILE: recv_sl.c */
  869.